class Subject:
    """课程类"""

    def __init__(self, name, code):
        self.name = name  # 课程名称
        self.code = code  # 课程代码
        self.instructors = []  # 授课教师
        self.students = []  # 选课学生

    def add_instructor(self, instructor):
        if isinstance(instructor, Instructor) and instructor not in self.instructors:
            self.instructors.append(instructor)

    def add_student(self, student):
        if isinstance(student, Student) and student not in self.students:
            self.students.append(student)

    def __str__(self):
        return f"Subject({self.name}, {self.code})"


class Instructor:
    """指导教师类"""

    def __init__(self, name, dept):
        self.name = name  # 教师姓名
        self.department = dept  # 所属系（至少1个）
        self.subjects = []  # 教授的课程（1-3门）
        dept.add_instructor(self)  # 自动关联到系

    def add_subject(self, subject):
        if isinstance(subject, Subject) and len(self.subjects) < 3:
            self.subjects.append(subject)
            subject.add_instructor(self)
        else:
            raise ValueError("Instructor can teach at most 3 subjects!")

    def __str__(self):
        return f"Instructor({self.name})"


class Department:
    """系类"""

    def __init__(self, name, school):
        self.name = name  # 系名称
        self.school = school  # 所属学院
        self.instructors = []  # 指导教师（至少1位）
        self.subjects = []  # 提供的课程（至少1门）
        school.add_department(self)  # 自动关联到学院

    def add_instructor(self, instructor):
        if isinstance(instructor, Instructor) and instructor not in self.instructors:
            self.instructors.append(instructor)

    def add_subject(self, subject):
        if isinstance(subject, Subject) and subject not in self.subjects:
            self.subjects.append(subject)

    def __str__(self):
        return f"Department({self.name})"


class Student:
    """学生类"""

    def __init__(self, name, school):
        self.name = name  # 学生姓名
        self.school = school  # 所属学院
        self.subjects = []  # 选修课程（1-5门）
        school.add_student(self)  # 自动关联到学院

    def add_subject(self, subject):
        if isinstance(subject, Subject) and len(self.subjects) < 5:
            self.subjects.append(subject)
            subject.add_student(self)
        else:
            raise ValueError("Student can take at most 5 subjects!")

    def __str__(self):
        return f"Student({self.name})"


class School:
    """学院类"""

    def __init__(self, name):
        self.name = name  # 学院名称
        self.departments = []  # 下属系（1..*）
        self.students = []  # 学生（0..*）

    def add_department(self, dept):
        if isinstance(dept, Department) and dept not in self.departments:
            self.departments.append(dept)

    def add_student(self, student):
        if isinstance(student, Student) and student not in self.students:
            self.students.append(student)

    def show_info(self):
        """展示学院完整信息"""
        print(f"=== {self.name} ===")

        # 打印系信息
        for dept in self.departments:
            print(f"\n{dept}:")
            print("  Instructors:")
            for instructor in dept.instructors:
                print(f"    - {instructor}: {[str(s) for s in instructor.subjects]}")
            print("  Subjects:")
            for subject in dept.subjects:
                print(f"    - {subject}")

        # 打印学生信息
        print("\nStudents:")
        for student in self.students:
            print(f"  - {student}: {[str(s) for s in student.subjects]}")


# 测试代码
if __name__ == "__main__":
    # 创建学院
    school = School("Sunnydale University")

    # 创建系
    cs_dept = Department("Computer Science", school)
    math_dept = Department("Mathematics", school)

    # 创建课程
    python_subj = Subject("Python Programming", "CS101")
    algo_subj = Subject("Algorithms", "CS202")
    calc_subj = Subject("Calculus I", "MATH101")

    # 将课程添加到对应系
    cs_dept.add_subject(python_subj)
    cs_dept.add_subject(algo_subj)
    math_dept.add_subject(calc_subj)

    # 创建教师并分配课程
    instructor1 = Instructor("Alice Smith", cs_dept)
    instructor1.add_subject(python_subj)
    instructor1.add_subject(algo_subj)

    instructor2 = Instructor("Bob Johnson", math_dept)
    instructor2.add_subject(calc_subj)

    # 创建学生并选课
    student1 = Student("Charlie Brown", school)
    student1.add_subject(python_subj)
    student1.add_subject(calc_subj)

    student2 = Student("Diana Prince", school)
    student2.add_subject(algo_subj)
    student2.add_subject(python_subj)
    student2.add_subject(calc_subj)

    # 展示学院信息
    school.show_info()